package filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 管理页面过滤器
 * tip:
 * 1.Filter过滤器只关心请求的地址是否匹配，不关心请求的资源是否存在
 * 2.filter在web工程启动时，由tomcat来创建filter实例，只会创建一个
 * 3.会调用filter默认的无参构造器，同时会调用init()，只调用一次
 * 4.在创建filter实例时，同时会创建一个FilterConfig对象，并通过init方法传入
 * 5.通过FilterConfig对象，可以获取该filter的相关配置信息
 * 6.当一个http请求的uri和该filter的url-pattern匹配时，就会调用doFilter方法
 * 7.在调用doFilter方法时，tomcat会同时创建 servletRequest 和 servletResponse对象 和 FilterChain对象
 *      并通过doFilter方法传入
 * 8.如果后面的请求目标资源(jsp, servlet)会使用到request 和 response，那么会继续传递
 */
public class ManagerFilter implements Filter {

    private int count = 0;
    //回忆实现tomcat+servlet底层机制时，相当于在tomcat又维护了关于filter对象和url-pattern关联的map
    //在handler处理请求时，会先根据请求的uri判断是否和hashmap中的某个url-pattern(key)匹配
    //如果匹配，就执行doFilter方法，相当于做了个拦截
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //当tomcat创建Filter后，会调用该方法，进行初始化
        System.out.println("ManagerFilter init()被调用...");
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //当每次调用该filter时，doFilter就会被调用
        System.out.println("ManagerFilter doFilter()被调用的次数 = " + (++count));
        //这里可以实现各种业务

        //如果继续访问目标资源->等价于放行
        //在调用filter之前,ServletRequest和ServletResponse对象已经被创建和封装好了
        //所以这里可以通过request获取很多信息，比如session
        //可以完成事务管理，数据获取，日志管理

        //获取到session
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object username = session.getAttribute("username");
        if (username == null) {
            //没有获取到session，转发到登录页面
            servletRequest.getRequestDispatcher("/login.jsp")
                    .forward(servletRequest, servletResponse);
        } else {
            //获取到session，代表用户登陆过，放行
            //filterChain.doFilter
            //1.继续访问目标资源url
            //2.servletRequest 和 servletResponse 对象会传递给目标资源/文件
            //3.doFilter传递的两个对象，在后面的 servlet/jsp 是同一个对象(指的是同一个http请求)
            System.out.println("servletRequest = " + servletRequest);
            filterChain.doFilter(servletRequest, servletResponse);
        }

    }

    @Override
    public void destroy() {
        //当filter被销毁时，destroy()就会调用
        System.out.println("ManagerFilter destroy()被调用...");
    }
}
